#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
生产环境配置

生产环境的特定配置，继承自基础配置并覆盖相应的值。
注重安全性、性能和稳定性。
所有配置通过环境变量设置，无需额外的配置文件。

作者: AI Assistant
创建时间: 2024
"""

import os
import secrets
from .base_config import BaseConfig


class ProductionConfig(BaseConfig):
    """生产环境配置
    
    必需的环境变量：
    - DB_PASSWORD: 数据库密码 (必需)
    - SECRET_KEY: Flask密钥 (必需，建议32位随机字符串)
    
    可选的环境变量：
    - DB_TYPE: 数据库类型 (默认: postgresql)
    - DB_HOST: 数据库主机 (默认: localhost)
    - DB_PORT: 数据库端口 (默认: 5432)
    - DB_NAME: 数据库名称 (默认: wechat_robot_prod)
    - DB_USER: 数据库用户名 (默认: wechat_robot_user)
    - DB_SSLMODE: SSL模式 (默认: require)
    - FLASK_HOST: Flask主机 (默认: 0.0.0.0)
    - FLASK_PORT: Flask端口 (默认: 5000)
    - LOG_LEVEL: 日志级别 (默认: INFO)
    - LOG_FILE: 日志文件路径 (默认: /var/log/wechat_robot/wechat_robot.log)
    - WECHAT_AUTO_REPLY: 自动回复 (默认: true)
    - WECHAT_WELCOME: 欢迎消息 (默认: false)
    - NEWS_ENABLED: 新闻推送 (默认: false)
    - CORS_ORIGINS: 跨域源 (默认: 空，不允许跨域)
    - API_ACCESS_TOKEN: API访问令牌 (建议设置)
    - MAX_UPLOAD_SIZE: 最大上传大小MB (默认: 20)
    """
    
    def __init__(self):
        super().__init__()
        
        # 数据库配置 - 生产环境使用PostgreSQL
        self.database.type = os.getenv('DB_TYPE', 'postgresql')
        self.database.host = os.getenv('DB_HOST', 'localhost')
        self.database.port = int(os.getenv('DB_PORT', 5432))
        self.database.database = os.getenv('DB_NAME', 'wechat_robot_prod')
        self.database.username = os.getenv('DB_USER', 'wechat_robot_user')
        self.database.password = os.getenv('DB_PASSWORD', '')
        self.database.sslmode = os.getenv('DB_SSLMODE', 'require')  # 生产环境要求SSL
        self.database.timeout = int(os.getenv('DB_TIMEOUT', 30))
        self.database.application_name = os.getenv('DB_APP_NAME', 'wechat_robot_prod')
        
        # Flask配置 - 生产环境
        self.flask.host = os.getenv('FLASK_HOST', '0.0.0.0')
        self.flask.port = int(os.getenv('FLASK_PORT', 5000))
        self.flask.debug = False
        self.flask.testing = False
        self.flask.environment = 'production'
        self.flask.secret_key = os.getenv('SECRET_KEY') or self._generate_secret_key()
        
        # 日志配置 - 生产环境
        self.logger.level = os.getenv('LOG_LEVEL', 'INFO')
        self.logger.file_path = os.getenv('LOG_FILE', '/var/log/wechat_robot/wechat_robot.log')
        self.logger.console_output = os.getenv('LOG_CONSOLE', 'false').lower() == 'true'
        self.logger.file_output = os.getenv('LOG_FILE_OUTPUT', 'true').lower() == 'true'
        self.logger.max_size = int(os.getenv('LOG_MAX_SIZE', 50))  # 50MB
        self.logger.backup_count = int(os.getenv('LOG_BACKUP_COUNT', 10))
        self.logger.format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        
        # 微信配置 - 生产环境
        self.wechat.auto_reply_enabled = os.getenv('WECHAT_AUTO_REPLY', 'true').lower() == 'true'
        self.wechat.default_reply_message = os.getenv('WECHAT_REPLY_MESSAGE', '收到！')
        self.wechat.welcome_enabled = os.getenv('WECHAT_WELCOME', 'false').lower() == 'true'
        self.wechat.welcome_template = os.getenv('WECHAT_WELCOME_TEMPLATE', '欢迎 @{member_name} 加入群聊！🎉')
        
        # 新闻配置 - 生产环境
        self.news.enabled = os.getenv('NEWS_ENABLED', 'false').lower() == 'true'
        self.news.push_time = os.getenv('NEWS_PUSH_TIME', '09:00')
        self.news.api_key = os.getenv('NEWS_API_KEY')
        
        # 安全配置 - 生产环境严格
        self.security.api_access_token = os.getenv('API_ACCESS_TOKEN') or self._generate_api_token()
        cors_origins = os.getenv('CORS_ORIGINS', '')
        if cors_origins:
            self.security.cors_origins = [origin.strip() for origin in cors_origins.split(',')]
        else:
            self.security.cors_origins = []  # 生产环境默认不允许跨域
        self.security.max_upload_size = int(os.getenv('MAX_UPLOAD_SIZE', 20))  # 20MB
        
        # 路径配置 - 生产环境
        self.paths.backup_dir = os.getenv('BACKUP_DIR', '/var/backups/wechat_robot')
        self.paths.temp_dir = os.getenv('TEMP_DIR', '/tmp/wechat_robot')
        self.paths.log_dir = os.getenv('LOG_DIR', '/var/log/wechat_robot')
        
        # 确保生产环境目录存在
        self._ensure_production_directories()
        
        # 验证生产环境必需配置
        self._validate_production_config()
    
    def _generate_secret_key(self):
        """生成安全的密钥"""
        return secrets.token_urlsafe(32)
    
    def _generate_api_token(self):
        """生成API访问令牌"""
        return secrets.token_urlsafe(32)
    
    def _ensure_production_directories(self):
        """确保生产环境目录存在"""
        from pathlib import Path
        
        directories = [
            self.paths.backup_dir,
            self.paths.temp_dir,
            self.paths.log_dir
        ]
        
        for directory in directories:
            try:
                Path(directory).mkdir(parents=True, exist_ok=True)
            except PermissionError:
                # 生产环境可能没有权限创建某些目录，记录警告
                print(f"警告: 无法创建目录 {directory}，请确保目录存在且有适当权限")
    
    def _validate_production_config(self):
        """验证生产环境必需配置"""
        errors = []
        
        # 检查数据库密码
        if not self.database.password:
            errors.append("生产环境必须设置数据库密码 (DB_PASSWORD)")
        
        # 检查密钥
        if self.flask.secret_key == 'dev-secret-key-change-in-production':
            errors.append("生产环境必须设置安全的SECRET_KEY")
        
        # 检查API令牌
        if not self.security.api_access_token:
            errors.append("生产环境建议设置API访问令牌 (API_ACCESS_TOKEN)")
        
        if errors:
            error_message = "生产环境配置验证失败:\n" + "\n".join(f"- {error}" for error in errors)
            raise ValueError(error_message)
    
    def get_flask_config(self):
        """获取Flask配置字典 - 生产环境特定"""
        config = super().get_flask_config()
        
        # 生产环境特定配置
        config.update({
            'DEBUG': False,
            'TESTING': False,
            'SQLALCHEMY_ECHO': False,  # 生产环境不输出SQL
            'SQLALCHEMY_RECORD_QUERIES': False,
            'SQLALCHEMY_ENGINE_OPTIONS': {
                'pool_timeout': self.database.timeout,
                'pool_recycle': 3600,
                'pool_pre_ping': True,  # 连接池预检查
                'pool_size': 10,  # 连接池大小
                'max_overflow': 20  # 最大溢出连接
            },
            'PERMANENT_SESSION_LIFETIME': 3600,  # 会话超时时间
            'SESSION_COOKIE_SECURE': True,  # HTTPS环境下的安全cookie
            'SESSION_COOKIE_HTTPONLY': True,  # 防止XSS
            'SESSION_COOKIE_SAMESITE': 'Lax',  # CSRF保护
        })
        
        return config
    
    def to_dict(self):
        """转换为字典格式 - 包含生产环境标识"""
        config_dict = super().to_dict()
        config_dict['environment'] = 'production'
        config_dict['description'] = '生产环境配置'
        
        # 生产环境不暴露敏感信息
        if 'database' in config_dict and 'password' in config_dict['database']:
            config_dict['database']['password'] = '***'
        if 'flask' in config_dict and 'secret_key' in config_dict['flask']:
            config_dict['flask']['secret_key'] = '***'
        if 'security' in config_dict and 'api_access_token' in config_dict['security']:
            config_dict['security']['api_access_token'] = '***'
        
        return config_dict
    
    def get_security_headers(self):
        """获取生产环境安全头"""
        return {
            'X-Content-Type-Options': 'nosniff',
            'X-Frame-Options': 'DENY',
            'X-XSS-Protection': '1; mode=block',
            'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
            'Content-Security-Policy': "default-src 'self'",
            'Referrer-Policy': 'strict-origin-when-cross-origin'
        }
    
    def is_https_required(self):
        """生产环境是否要求HTTPS"""
        return True
    
    def get_rate_limit_config(self):
        """获取速率限制配置"""
        return {
            'default': '100 per hour',
            'api': '1000 per hour',
            'upload': '10 per minute'
        }